package com.ale.oxetool.controller;

import com.ale.oxetool.model.BatchSwitchTask;
import com.ale.oxetool.model.SwitchTask;
import com.ale.oxetool.service.GridService;
import com.ale.oxetool.service.SwitchTaskService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletContext;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by guoshunw on 2016/3/30.
 */

@Controller
public class PhoneController {

    private static final String SESSION_TASK_KEY = "batchTask";
    @Autowired
    private GridService gridService;

    @Autowired
    private SwitchTaskService switchTaskService;

    @Autowired
    private ServletContext ctx;

    private static Logger log = LoggerFactory.getLogger(PhoneController.class);


    @RequestMapping("/clearSwitchTasks")
    @ResponseBody
    public Map clearSwitchTasks() {
        Map<String, Object> result = new HashMap<>();
        BatchSwitchTask task = (BatchSwitchTask) ctx.getAttribute(SESSION_TASK_KEY);

        if (null != task && !task.isCompleted()) {
            List<SwitchTask> inProgressTasks = task.getStatusTasks(SwitchTask.IN_PROGRESS);
            int code = 0;
            String msg;
            if (inProgressTasks.isEmpty()) {
                log.info("Remove last switch task {}", task);
                ctx.removeAttribute(SESSION_TASK_KEY);
                msg = "Batch switch task cancel successful";
            } else {
                code = -1;
                msg = "There are still " + inProgressTasks.size() + " switch task is in progress, please wait until they are success or fail!";
            }
            result.put("code", code);
            result.put("message", msg);
            return result;
        }
        //start switch process

        result.put("code", 0);
        result.put("message", "No exception status!");
        return result;
    }

    @RequestMapping("/startSwitchPhones")
    @ResponseBody
    public Map startSwitchTasks(@RequestParam(value = "switchTasks[]") List<String> switchTasks) {
        log.debug("Request parameters: {}", switchTasks);
        Map<String, Object> result = new HashMap<>();
        BatchSwitchTask task = (BatchSwitchTask) ctx.getAttribute(SESSION_TASK_KEY);

        if (null != task && !task.isCompleted()) {
            result.put("code", -1);
            result.put("message", "Last batch switch task is still in progress!");
            return result;
        }
        //start switch process
        try {
            BatchSwitchTask sts = switchTaskService.startTask(switchTasks);
            // auto remove the last switch task
            ctx.setAttribute(SESSION_TASK_KEY, sts);

        } catch (IOException e) {
            e.printStackTrace();
        }
        result.put("code", 0);
        result.put("message", "Switch task started...");
        return result;
    }

    @RequestMapping("/showSwitchingPhones")
    @ResponseBody
    public Map<String, Object> getSwitchTasksPhones(@RequestParam(required = false, defaultValue = "-1") long lastModified,
                                                    @RequestParam(required = false, defaultValue = "asc") String sord,
                                                    @RequestParam(required = false, defaultValue = "phone.name") String sidx,
                                                    @RequestParam(required = false, defaultValue = "-1") int rows,
                                                    @RequestParam(required = false, defaultValue = "1") int page,
                                                    @RequestParam(required = false, defaultValue = "phone.mac") String idProp,
                                                    @RequestParam(required = false, defaultValue = "phone.name, phone.ipAddr, phone.type, phone.number, targetPlatform, status, description") String colProps,
                                                    @RequestParam(required = false) String filters
    ) throws Exception {
        BatchSwitchTask task = (BatchSwitchTask) ctx.getAttribute(SESSION_TASK_KEY);

        HashMap<String, Object> userData = new HashMap<>();

        if (null == task) {
            log.info("There's no batchSwitchTask in current session");
            userData.put("switchCompleted", true);
            userData.put("lastModified", -1);

            return gridService.getPagedList(Collections.EMPTY_LIST, colProps, idProp, sord, sidx, page, rows, filters, userData);
        }
        log.debug("Refresh switch tasks... {}", task.getTasks());
        //update batchSwitchTask status after refresh
        //this will block task grid from reading(), because it was blocked in checkSwitchStatus, so we just don't block here
//        List<SwitchTask> tasks = task.getOrWaitTask(lastModified);
        List<SwitchTask> tasks = task.getTasks();

        userData.put("switchCompleted", task.isCompleted());
        userData.put("lastModified", task.getLastModified());

        Map<String, Object> result = gridService.getPagedList(tasks, colProps, idProp, sord, sidx, page, rows, filters, userData);

        if (task.isCompleted()) {
            log.info("Switch task {} has been completed", task);
            // Do not remove this task, remove it at next switch process.
            //session.removeAttribute(SESSION_TASK_KEY);
        }
        return result;
    }

    @RequestMapping("/checkSwitchStatus")
    @ResponseBody
    public Map checkSwitchState(@RequestParam(required = false, defaultValue = "-1") long lastModified) {
        HashMap<String, Object> ret = new HashMap<>();
        BatchSwitchTask batchSwitchTask = (BatchSwitchTask) ctx.getAttribute(SESSION_TASK_KEY);

        ret.put("code", 0);

        if (null == batchSwitchTask) {
            ret.put("completed", true);
            return ret;
        }
        // this block may case deadlock
//        batchSwitchTask.getOrWaitTask(lastModified);

        ret.put("completed", batchSwitchTask.isCompleted());
        return ret;
    }


    @RequestMapping("/phones")
    public
    @ResponseBody
    Map getPhones(@RequestParam(required = false, defaultValue = "asc") String sord,
                  @RequestParam(required = false, defaultValue = "name") String sidx,
                  @RequestParam(required = false, defaultValue = "-1") int rows,
                  @RequestParam(required = false, defaultValue = "1") int page,
                  @RequestParam(required = false, defaultValue = "mac") String idProp,
                  @RequestParam(required = false, defaultValue = "name, mac, ipVer, ipAddr, type, qmcdu, OXE1, OXE2") String colProps,
                  @RequestParam(required = false) String filters
    ) throws Exception {
        log.debug("colProps={}, idProp={}, sord={}, sidx={}, rows={}, page={}, filters={}", colProps, idProp, sord, sidx, rows, page, filters);
        return gridService.getPagedPhones(colProps, idProp, sord, sidx, page, rows, filters);
    }
}
